package com.codeoss.framework.workflow.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.codeoss.framework.expression.Expression;
import com.codeoss.framework.expression.IScriptServiceStore;
import com.codeoss.framework.workflow.context.WorkflowContext;
import com.codeoss.framework.workflow.def.ForkNodeDef;
import com.codeoss.framework.workflow.def.LineDef;
import com.codeoss.framework.workflow.def.WorkflowDef;
import com.codeoss.framework.workflow.store.IWorkflowStore;
import com.codeoss.module.workflow.model.WorkflowToken;
import com.codeoss.module.workflow.service.IWorkflowTokenService;

@Service
public class ForkNodeService extends AbstractNodeService{
	@Autowired
    private IScriptServiceStore scriptServiceStore;
	@Autowired
	private IWorkflowStore workflowStore;
	@Autowired
	private IWorkflowTokenService workflowTokenService;
	@Override
	@Transactional
	public void execute(WorkflowContext workflowContext) {
		// TODO Auto-generated method stub
		ForkNodeDef forkNodeDef=(ForkNodeDef)workflowContext.getNodeDef();
		Map<String,Object> bindingMap=new HashMap<String,Object>();
		bindingMap.put("workflowContext", workflowContext);
		Expression forkExpression=forkNodeDef.getForkExpression();
		List<String> transitionList=null;
		Long workflowWorkflowId=workflowContext.getWorkflowProcess().getWorkflowWorkflowId();
		WorkflowDef workflowDef=workflowStore.get(workflowWorkflowId);
		List<LineDef> lineList=workflowDef.getLineList();
		if(forkExpression!=null) {
			transitionList=scriptServiceStore.getScriptService(forkExpression).eval(forkExpression.getScript(), bindingMap);
		}else{
			transitionList=new ArrayList<String>();
			
			for(int i=0;i<lineList.size();i++) {
				LineDef lineDef=lineList.get(i);
				if(lineDef.getFromNodeId().equals(forkNodeDef.getId())) {
					transitionList.add(lineDef.getName());
				}
			}
		}
		
		List<WorkflowToken> subTokenList=new ArrayList<WorkflowToken>();
		
		for(int i=0;i<transitionList.size();i++) {
			WorkflowToken workflowToken=new WorkflowToken();
			subTokenList.add(workflowToken);
			
			workflowToken.setParentTokenId(workflowContext.getWorkflowToken().getId());
			workflowToken.setWorkflowActivityInstanceId(workflowContext.getWorkflowActivityInstance().getId());
			
			workflowTokenService.insert(workflowToken);
		}
		
		for(int i=0;i<transitionList.size();i++) {
			WorkflowToken workflowToken=subTokenList.get(i);
			WorkflowContext subWorkflowContext=new WorkflowContext();
			subWorkflowContext.setWorkflowToken(workflowToken);
			subWorkflowContext.setWorkflowProcess(workflowContext.getWorkflowProcess());
			subWorkflowContext.setWorkflowActivityInstance(workflowContext.getWorkflowActivityInstance());
			subWorkflowContext.setWorkflowActivity(workflowContext.getWorkflowActivity());
			subWorkflowContext.setBizKey(workflowContext.getWorkflowProcess().getBizKey());
			subWorkflowContext.setApproved(workflowContext.getApproved());
			String transitionName=transitionList.get(i);
			
			for(int j=0;j<lineList.size();j++) {
				if(lineList.get(j).getName().equals(transitionName)) {
					subWorkflowContext.setNodeDef(lineList.get(j).getToNode());
					break;
				}
			}
			end(subWorkflowContext, transitionList.get(i));
		}
	}
}
